package common.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import common.interf.IQueryHandle;
@SuppressWarnings("unchecked")
public class QueryHandleImpl implements IQueryHandle{
	public Map query(Map map,String qfname) 
		throws Exception{
		if(null == map)
			return null;
		List<String> fieldArr = new ArrayList<String>(); 
		//解析xml
		SAXReader reader = new SAXReader();   
		Document  doc = reader.read(new File(qfname));  
		Element root = doc.getRootElement();
		//table list
		List<Element> tlst = root.elements("table");
		if(tlst.size() == 0)
			return null;
		String selectClause = "select ";
		String fromClause = " from ";
		String whereClause = " where ";
		boolean se = false;
		boolean wh = false;
		int ii=0;
		for(Iterator<Element> tite=tlst.iterator();tite.hasNext();ii++){
			Element etbl = tite.next();
			//field list
			List<Element> flst = etbl.elements("field");
			if(flst.size() == 0)
				continue;
			String tbl = etbl.attributeValue("name");
			for(Iterator<Element> fite=flst.iterator();fite.hasNext();){
				Element fe = fite.next();
				String type = fe.attributeValue("type");
				String fname = fe.attributeValue("name");
				String fis= fe.attributeValue("string");
				boolean bIsString = (fis!=null && fis.equals("true"))?true:false;
				//type default all
				if(null == type)  
					type = "all";
				//添加到select
				if(type.equals("all") || type.equals("s")){
					if(se)
						selectClause += ',';
					selectClause += tbl + "." + fname;
					
					String retName = fe.attributeValue("retname");
					if(!StringUtils.isEmpty(retName))
						selectClause += " as " + retName;
					else
						retName = fname;
						
					fieldArr.add(retName);
					se = true;
				}
				//条件 
				if(type.equals("all") || type.equals("q")){
					//condition list
					String fvalue = (map.get(fname)==null)?null:map.get(fname).toString();
					List<Element> clst = fe.elements();
					if(clst.size() == 0){  //无条件，默认为以字段名进行查询
						if(null == fvalue)
							continue;
						if(wh)
							whereClause += " and ";
						if(bIsString)
							fvalue = "'" + fvalue + "'";
						whereClause += tbl + "." + fname + "=" + fvalue;
						wh = true;
					}else{   //有条件，按照条件进行查询
						for(int i=0,len=clst.size();i<len;i++){
							Element con = clst.get(i);
							String rn = con.attributeValue("name");
							String fn = tbl + "." + fname;
							if(StringUtils.isEmpty(rn))
								rn = "=";
							fn +=  " " + rn + " ";
							// value field
							String fv = con.attributeValue("vfield");
							//condition 字段是否为空
							boolean bEmptyFv = StringUtils.isEmpty(fv); 
							//与其它表相关字段,采用Left Join关联
							if(!bEmptyFv && fv.indexOf(".") > -1){
								int ind1 = fv.indexOf(".");
								String tbl1 = fv.substring(0,ind1);  
								if(fromClause.indexOf(tbl1 + " ") > -1){
									//已经left join 该表
									int ind2 = fromClause.indexOf(" left join " + tbl); 
									if(ind2 > -1)
										fromClause += " and " + fn + fv;
									else
										fromClause += " left join " + tbl + " on " + fn + fv;
									continue;
								}
							}else{  //where 条件
								if(!bEmptyFv)
									fvalue = (map.get(fv)==null)?null:map.get(fv).toString();
								if(StringUtils.isEmpty(fvalue))
									continue;
								if(rn.equals("like"))
									fvalue = "%" + fvalue + "%";
								if(bIsString)
									fvalue = "'" + fvalue + "'";
								fn += fvalue;
							}
							if(wh)
								whereClause += " and ";
							whereClause += fn;
							wh = true;
						}
					}
				}
			}
			if(fromClause.indexOf(tbl + " ") == -1){
				if(ii > 0)
					fromClause += ",";
				fromClause += tbl + " ";
			}
		}
		//组合整个查询sql
		String sql = selectClause;
		sql += fromClause;
		if(wh)
			sql += whereClause;
		Map<String,Object> rmap = new HashMap<String,Object>();
		rmap.put("sql", sql);
		rmap.put("fieldArr", fieldArr);
		return rmap;
	}
}
